</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><varname>root.transient-ro</varname></term>
+ <listitem><para>A boolean value; the default is <literal>false</literal>.
+ This is like <literal>root.transient</literal>, but the overlayfs upper will be mounted
+ read-only by default. Use this when you want specific privileged components to be able to
+ write to the upper by temporarily mounting it writable in a new mount namespace.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term><varname>composefs.enabled</varname></term>
<listitem><para>This can be <literal>yes</literal>, <literal>no</literal>, <literal>maybe</literal>,
if (!ot_keyfile_get_boolean_with_default (config, ROOT_KEY, OTCORE_PREPARE_ROOT_TRANSIENT_KEY,
FALSE, &ret->root_transient, error))
return NULL;
+ if (!ot_keyfile_get_boolean_with_default (config, ROOT_KEY, OTCORE_PREPARE_ROOT_TRANSIENT_RO_KEY,
+ FALSE, &ret->root_transient_ro, error))
+ return NULL;
+ if (ret->root_transient && ret->root_transient_ro)
+ {
+ return glnx_null_throw (error, "Cannot set both root.transient and root.transient-ro");
+ }
+ // This way callers can test for just root_transient
+ else if (ret->root_transient_ro)
+ {
+ ret->root_transient = TRUE;
+ }
g_autofree char *enabled = g_key_file_get_value (config, OTCORE_PREPARE_ROOT_COMPOSEFS_KEY,
OTCORE_PREPARE_ROOT_ENABLED_KEY, NULL);
/* Pass on the state */
g_variant_builder_add (metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT,
g_variant_new_boolean (rootfs_config->root_transient));
+ g_variant_builder_add (metadata_builder, "{sv}", OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT_RO,
+ g_variant_new_boolean (rootfs_config->root_transient_ro));
bool using_composefs = FALSE;
#ifdef HAVE_COMPOSEFS
cfs_options.workdir = root_workdir;
cfs_options.upperdir = root_upperdir;
+ if (rootfs_config->root_transient_ro)
+ cfs_options.flags = LCFS_MOUNT_FLAGS_READONLY;
}
else
{
{
OtTristate composefs_enabled;
gboolean root_transient;
+ gboolean root_transient_ro;
gboolean require_verity;
gboolean is_signed;
char *signature_pubkey;
#define OTCORE_PREPARE_ROOT_ENABLED_KEY "enabled"
#define OTCORE_PREPARE_ROOT_KEYPATH_KEY "keypath"
#define OTCORE_PREPARE_ROOT_TRANSIENT_KEY "transient"
+#define OTCORE_PREPARE_ROOT_TRANSIENT_RO_KEY "transient-ro"
// For use with systemd soft reboots
#define OTCORE_RUN_NEXTROOT "/run/nextroot"
#define OTCORE_RUN_BOOTED_KEY_COMPOSEFS_SIGNATURE "composefs.signed"
// This key will be present if the root is transient
#define OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT "root.transient"
+// This key will be present if the root is transient readonly
+#define OTCORE_RUN_BOOTED_KEY_ROOT_TRANSIENT_RO "root.transient-ro"
// This key will be present if the sysroot-ro flag was found
#define OTCORE_RUN_BOOTED_KEY_SYSROOT_RO "sysroot-ro"
// Always holds the (device, inode) pair of the booted deployment
const bool sysroot_currently_writable = !path_is_on_readonly_fs (root_arg);
g_print ("sysroot.readonly configuration value: %d (fs writable: %d)\n", (int)sysroot_readonly,
(int)sysroot_currently_writable);
+ if (rootfs_config->root_transient)
+ {
+ g_print ("root.transient: %d (ro: %d)\n", (int)rootfs_config->root_transient,
+ (int)rootfs_config->root_transient_ro);
+ }
/* Remount root MS_PRIVATE here to avoid errors due to the kernel-enforced
* constraint that disallows MS_SHARED mounts to be moved.
--- /dev/null
+#!/bin/bash
+set -xeuo pipefail
+
+. ${KOLA_EXT_DATA}/libinsttest.sh
+
+prepare_tmpdir
+
+echo "testing boot=${AUTOPKGTEST_REBOOT_MARK:-}"
+
+# Print this by default on each boot
+ostree admin status
+
+case "${AUTOPKGTEST_REBOOT_MARK:-}" in
+ "")
+ # xref https://github.com/coreos/coreos-assembler/pull/2814
+ systemctl mask --now zincati
+
+ test '!' -w /
+
+ cp /usr/lib/ostree/prepare-root.conf /etc/ostree/
+ cat >> /etc/ostree/prepare-root.conf <<'EOF'
+[root]
+transient-ro = true
+EOF
+
+ rpm-ostree initramfs-etc --track /etc/ostree/prepare-root.conf
+
+ /tmp/autopkgtest-reboot "2"
+ ;;
+ "2")
+
+ test '!' -w '/'
+
+ unshare -m /bin/sh -c 'env LIBMOUNT_FORCE_MOUNT2=always mount -o remount,rw / && mkdir /new-dir-in-root'
+ test -d /new-dir-in-root
+
+ test '!' -w '/'
+
+ echo "ok root transient-ro"
+ ;;
+ *)
+ fatal "Unexpected AUTOPKGTEST_REBOOT_MARK=${AUTOPKGTEST_REBOOT_MARK}"
+ ;;
+esac